package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.NoBackBizException;
import com.eastfair.home.entity.ReportVenueSpace;
import com.eastfair.venueservice.dao.ReportVenueSpaceAuditMapper;
import com.eastfair.venueservice.dto.ReportVenueDrawingCategoryAuditDTO;
import com.eastfair.venueservice.dto.ReportVenueSpaceAuditDTO;
import com.eastfair.venueservice.entity.ReportVenueSpaceAudit;
import com.eastfair.venueservice.enumeration.ReportVenueSpaceAuditDrawingAuditStatusEnum;
import com.eastfair.venueservice.enumeration.ReportVenueSpaceAuditReportSpaceStatusEnum;
import com.eastfair.venueservice.exceptioncode.VenueServiceExceptionCode;
import com.eastfair.venueservice.service.ReportVenueDrawingCategoryAuditService;
import com.eastfair.venueservice.service.ReportVenueSpaceAuditService;
import com.eastfair.venueservice.service.ServiceBookingService;
import com.eastfair.venueservice.service.VenueManageReportVenueSpaceService;
import com.eastfair.venueservice.vo.ReportVenueSpaceAuditVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 一键报馆审核记录
 * </p>
 *
 * @author dq
 * @date 2022-09-07
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ReportVenueSpaceAuditServiceImpl extends SuperServiceImpl<ReportVenueSpaceAuditMapper, ReportVenueSpaceAudit> implements ReportVenueSpaceAuditService {

    @Resource
    private ReportVenueDrawingCategoryAuditService reportVenueDrawingCategoryAuditService;

    @Resource
    private VenueManageReportVenueSpaceService venueManageReportVenueSpaceService;

    @Resource
    private ServiceBookingService serviceBookingService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ReportVenueSpaceAudit> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ReportVenueSpaceAudit model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());

        model.setDrawingAuditStatus(ReportVenueSpaceAuditDrawingAuditStatusEnum.SUBMIT);
        model.setReportSpaceStatus(ReportVenueSpaceAuditReportSpaceStatusEnum.SUBMIT);
        model.setLastReportTime(LocalDateTime.now());
        return R.successDef();
    }

    @Override
    public IPage<ReportVenueSpaceAuditVO> listReportVenueSpaceAuditVOs(PageParams<ReportVenueSpaceAuditDTO> pageParams) {
        log.info("listReportVenueSpaceAuditVOs - 分页查询报馆审核VO列表, pageParams={}", pageParams);
        IPage<ReportVenueSpaceAudit> page = listReportVenueSpaceAudits(pageParams);
        IPage<ReportVenueSpaceAuditVO> voPage = new Page<>();
        BeanUtil.copyProperties(page, voPage);
        List<ReportVenueSpaceAudit> list = page.getRecords();
        if (list == null || list.isEmpty()) {
            return voPage;
        }
        // 查询服务数量
        List<String> reportVenueSpaceNumbers = list.stream().map(ReportVenueSpaceAudit::getReportVenueSpaceNumber).collect(Collectors.toList());
        Map<String, Integer> map = serviceBookingService.queryBookingServiceNum(reportVenueSpaceNumbers);
        List<ReportVenueSpaceAuditVO> voList = list
                .stream()
                .map(reportVenueSpaceAudit -> {
                    ReportVenueSpaceAuditVO reportVenueSpaceAuditVO = BeanUtil.toBean(reportVenueSpaceAudit, ReportVenueSpaceAuditVO.class);
                    Integer num = map.get(reportVenueSpaceAuditVO.getReportVenueSpaceNumber());
                    reportVenueSpaceAuditVO.setServiceNum(Objects.nonNull(num) ? num :0);
                    return reportVenueSpaceAuditVO;
                })
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    @Override
    public IPage<ReportVenueSpaceAudit> listReportVenueSpaceAudits(PageParams<ReportVenueSpaceAuditDTO> pageParams) {
        Page<ReportVenueSpaceAudit> paramPage = pageParams.buildPage();
        ReportVenueSpaceAuditDTO param = pageParams.getModel();
        QueryWrapper<ReportVenueSpaceAudit> queryWrapper = createReportVenueSpaceAuditQueryWrapper(param);
        return page(paramPage, queryWrapper);
    }

    @Override
    public ReportVenueSpaceAuditVO getVOByReportVenueSpaceNumber(String reportVenueSpaceNumber) {
        log.info("getVOByReportVenueSpaceNumber - 一键报馆编号查询报馆审核记录, reportVenueSpaceNumber={}", reportVenueSpaceNumber);
        ReportVenueSpaceAudit reportVenueSpaceAudit = getByReportVenueSpaceNumber(reportVenueSpaceNumber);
        if (reportVenueSpaceAudit == null) {
            return null;
        }
        return BeanUtil.toBean(reportVenueSpaceAudit, ReportVenueSpaceAuditVO.class);
    }

    @Override
    public List<ReportVenueSpaceAudit> listReportVenueSpaceAudits(ReportVenueSpaceAuditDTO param) {
        QueryWrapper<ReportVenueSpaceAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ReportVenueSpaceAudit::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(StrUtil.isNotBlank(param.getReportVenueSpaceNumber()),
                        ReportVenueSpaceAudit::getReportVenueSpaceNumber, param.getReportVenueSpaceNumber())
        ;
        return list(queryWrapper);
    }

    @Override
    public ReportVenueSpaceAudit getByReportVenueSpaceNumber(String reportVenueSpaceNumber) {
        ReportVenueSpaceAuditDTO param = new ReportVenueSpaceAuditDTO();
        param.setReportVenueSpaceNumber(reportVenueSpaceNumber);
        List<ReportVenueSpaceAudit> list = listReportVenueSpaceAudits(param);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReportVenueSpaceAudit saveReportVenueSpaceAudit(ReportVenueSpaceAuditDTO reportVenueSpaceAuditDTO) {
        log.info("saveReportVenueSpaceAudit - 保存一键报馆审核记录, reportVenueSpaceAuditDTO={}", reportVenueSpaceAuditDTO);
        ReportVenueSpaceAudit reportVenueSpaceAudit = BeanUtil.toBean(reportVenueSpaceAuditDTO, ReportVenueSpaceAudit.class);
        save(reportVenueSpaceAudit);
        return reportVenueSpaceAudit;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitReportVenueSpaceAudit(ReportVenueSpaceAuditDTO reportVenueSpaceAuditDTO) {
        log.info("submitReportVenueSpaceAudit - 提交一键报馆审核记录, reportVenueSpaceAuditDTO={}", reportVenueSpaceAuditDTO);
        // 保存一键报馆审核记录
        removeByReportVenueSpaceNumber(reportVenueSpaceAuditDTO.getReportVenueSpaceNumber());
        ReportVenueSpaceAudit reportVenueSpaceAudit = saveReportVenueSpaceAudit(reportVenueSpaceAuditDTO);
        // 保存图纸分类审核列表
        List<ReportVenueDrawingCategoryAuditDTO> reportVenueDrawingCategoryAuditList = reportVenueSpaceAuditDTO.getReportVenueDrawingCategoryAuditList();
        return reportVenueDrawingCategoryAuditService.submitBatch(reportVenueDrawingCategoryAuditList, reportVenueSpaceAudit.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAuditStatus(ReportVenueSpaceAuditDTO reportVenueSpaceAuditDTO) {
        log.info("updateAuditStatus - 更新审核结果, reportVenueSpaceAuditDTO={}", reportVenueSpaceAuditDTO);
        ReportVenueSpaceAudit reportVenueSpaceAudit = getById(reportVenueSpaceAuditDTO.getId());
        if (ReportVenueSpaceAuditDrawingAuditStatusEnum.APPROVED.eq(reportVenueSpaceAudit.getDrawingAuditStatus())) {
            throw NoBackBizException.wrap(VenueServiceExceptionCode.REPORT_VENUE_SPACE_CAN_NOT_AUDIT.getCode(), "图纸已审核通过，不可再审核");
        }
        // 更新一键报馆审核记录的审核状态
        reportVenueSpaceAudit.setDrawingAuditStatus(reportVenueSpaceAuditDTO.getDrawingAuditStatus());
        reportVenueSpaceAudit.setDrawingAuditOpinion(reportVenueSpaceAuditDTO.getDrawingAuditOpinion());
        reportVenueSpaceAudit.setLastAuditTime(LocalDateTime.now());
        reportVenueSpaceAudit.setDrawingAuditUserId(reportVenueSpaceAuditDTO.getDrawingAuditUserId());
        reportVenueSpaceAudit.setDrawingAuditUserName(reportVenueSpaceAuditDTO.getDrawingAuditUserName());
        if (ReportVenueSpaceAuditDrawingAuditStatusEnum.APPROVED.eq(reportVenueSpaceAuditDTO.getDrawingAuditStatus())) {
            reportVenueSpaceAuditDTO.setReportSpaceStatus(ReportVenueSpaceAuditReportSpaceStatusEnum.APPROVED);
        } else {
            reportVenueSpaceAuditDTO.setReportSpaceStatus(ReportVenueSpaceAuditReportSpaceStatusEnum.NOT_APPROVED);
        }
        reportVenueSpaceAudit.setReportSpaceStatus(reportVenueSpaceAuditDTO.getReportSpaceStatus());
        updateById(reportVenueSpaceAudit);
        // 更新审核图纸列表的审核状态
        List<ReportVenueDrawingCategoryAuditDTO> reportVenueDrawingCategoryAuditList = reportVenueSpaceAuditDTO.getReportVenueDrawingCategoryAuditList();
        reportVenueDrawingCategoryAuditService.updateBatchAuditStatus(reportVenueDrawingCategoryAuditList);
        // 更新主场一键报馆记录的审核结果
        return venueManageReportVenueSpaceService.updateAuditStatus(reportVenueSpaceAudit);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByReportVenueSpaceNumber(String reportVenueSpaceNumber) {
        log.info("removeByReportVenueSpaceNumber - 报馆号移除审核记录={}", reportVenueSpaceNumber);
        ReportVenueSpaceAudit reportVenueSpaceAudit = getByReportVenueSpaceNumber(reportVenueSpaceNumber);
        if (reportVenueSpaceAudit == null) {
            return false;
        }
        List<ReportVenueSpaceAudit> list = new ArrayList<>();
        list.add(reportVenueSpaceAudit);
        return removeByIdsOfLogic(list);
    }

    /**
     * 创建ReportVenueSpaceAudit查询
     *
     * @param param ReportVenueSpaceAudit.
     * @return QueryWrapper.
     */
    private QueryWrapper<ReportVenueSpaceAudit> createReportVenueSpaceAuditQueryWrapper(ReportVenueSpaceAuditDTO param) {
        QueryWrapper<ReportVenueSpaceAudit> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(ReportVenueSpaceAudit::getIsDeleted, BusinessConstant.DELETE_NO)
                .like(StrUtil.isNotBlank(param.getReportVenueSpaceNumber()),
                        ReportVenueSpaceAudit::getReportVenueSpaceNumber, param.getReportVenueSpaceNumber())
                .like(StrUtil.isNotBlank(param.getHomeCourtName()),
                        ReportVenueSpaceAudit::getHomeCourtName, param.getHomeCourtName())
                .like(StrUtil.isNotBlank(param.getSpaceName()),
                        ReportVenueSpaceAudit::getSpaceName, param.getSpaceName())
                .eq(param.getDrawingAuditStatus() != null,
                        ReportVenueSpaceAudit::getDrawingAuditStatus, param.getDrawingAuditStatus())
                .eq(param.getId() != null, ReportVenueSpaceAudit::getId, param.getId())
                .eq(param.getHomeCourtId() != null, ReportVenueSpaceAudit::getHomeCourtId, param.getHomeCourtId())
                .eq(param.getExhibitionId() != null, ReportVenueSpaceAudit::getExhibitionId, param.getExhibitionId())
                .like(StrUtil.isNotBlank(param.getExhibitionName()), ReportVenueSpaceAudit::getExhibitionName, param.getExhibitionName())
        ;
        return queryWrapper;
    }
}
